//    Copyright (C) Kherty.  All rights reserved.
using System;

namespace OpenLS.Spreadsheet.Expressions
{
    abstract class FullRangeReference<T, TOther>: RangeReference, IRangeReferenceItem where T: Dimension where TOther: Dimension
    {
        protected FullRangeReference(DimensionReference<T, TOther> first, DimensionReference<T, TOther> last) 
        {
            _first = first;
            _last = last;
            this.Worksheet.AddWeakRangeChanging(OnRangeChanging);
            //\\add precondition first < last
        }

        private DimensionReference<T, TOther> _first;
        internal DimensionReference<T, TOther> First
        {
            get { return _first; }
            set
            {
                this.Worksheet.Workbook.AddUndoAction(First, l => First = l);
                _first = value;
            }
        }

        private DimensionReference<T, TOther> _last;
        internal  DimensionReference<T, TOther> Last
        {
            get { return _last; }
            set
            {
                this.Worksheet.Workbook.AddUndoAction(Last, l => Last = l);
                _last = value;
            }
        }

        protected override Range GetRange()
        {
             {
                if (typeof(T) == typeof(Column))
                    return new FullColumnRange((Column)(object)First.Anchor, (Column)(object)Last.Anchor);
                if (typeof (T) == typeof (Row))
                    return new FullRowRange((Row)(object)First.Anchor, (Row)(object)Last.Anchor);
                throw new NotImplementedException();
                }
        }
        public override Worksheet Worksheet
        {
            get { return First.Worksheet; }
        }

        public abstract int MinRowIndex { get; }
        public abstract int MaxRowIndex { get; }
        public abstract int MinColumnIndex { get; }
        public abstract int MaxColumnIndex { get; }

        public override string Label
        {
            get { return First.Label + ":" + Last.Label; }
        }

        IRangeReferenceItem IRangeReferenceItem.Offset(CellRelativeAddress address)
        {
            return (IRangeReferenceItem) Offset(address);
        }

       /* public override RangeReference Offsetold(CellRelativeAddress address)
        {
            DimensionReference<T> newFirst = First.OffsetDim(address);
            DimensionReference<T> newLast = Last.OffsetDim(address);
            return new FullRangeReference<T>(newFirst, newLast);
        }
        */

        private void OnRangeChanging(object sender, RangeChangeEventArgs e)
        {
            if (e.Type == RangeChangeType.Deletion)
            {
                OnRangeDeleting(e);
            }
        }

        protected abstract void OnRangeDeleting(RangeChangeEventArgs e);
    }
}

